﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
namespace Lxzhu.OpenGL
{
    public class Glut
    {
        private const string GlutDll = "glut32.dll";
        private const CallingConvention GlutCalling = CallingConvention.Cdecl;
        public static void glutInit()
        {
            string[] args = Environment.GetCommandLineArgs();
            int argc = args.Length;
            StringBuilder[] argv = new StringBuilder[argc];
            for (int i = 0; i < argc; i++)
            {
                argv[i] = new StringBuilder(args[i], args[i].Length);
            }
            glutInit(ref argc, argv);
        }
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        private static extern void glutInit(ref int argc, StringBuilder[] argv);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutInitDisplayMode([MarshalAs(UnmanagedType.U4)]GlutDisplayMode mode);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutInitWindowSize(int width, int height);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutInitWindowPosition(int x, int y);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutCreateWindow(string title);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutDisplayFunc(GlutDisplayFunctor display);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutIdleFunc(GlutIdleFunctor idle);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutReshapeFunc(GlutReshapeFunctor reshape);

        #region keyboard
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutKeyboardFunc(GlutKeyboardFunctor keyboard);
        //[DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        //public static extern void glutKeyboardUpFunc(GlutKeyboardFunctor keyboard);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern int glutGetModifiers();
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutSpecialFunc(GlutKeyboardFunctor keyboard);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutSpecialUpFunc(GlutKeyboardFunctor keyboard);
        #endregion
        #region mouse
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutMouseFunc(GlutMouseFunctor mouse);
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutMotionFunc(GlutMotionFunctor motion);
        #endregion
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutMainLoop();
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutSwapBuffers();
        [DllImport(GlutDll, CallingConvention = GlutCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glutPostRedisplay();
    }    
    public delegate void GlutDisplayFunctor();
    public delegate void GlutIdleFunctor();
    public delegate void GlutReshapeFunctor(int w,int h);
    public delegate void GlutMouseFunctor(GlutMouseButton button,GlutButtonState state,int x,int y);
    public delegate void GlutKeyboardFunctor(GlutKeyCode key, int x, int y);
    public delegate void GlutMotionFunctor(int x,int y);
}
